package com.iwhalecloud.citybrain.flow.platform.manager.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.enums.ProcessInstanceActionEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.application.common.threadlocal.CommonOperateLogHolder;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.ProcessInstanceMonitorService;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ConstanceVariable;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ErrorCode;
import com.iwhalecloud.citybrain.flow.platform.manager.common.client.HttpCommandDto;
import com.iwhalecloud.citybrain.flow.platform.manager.common.client.HttpCommandResultDto;
import com.iwhalecloud.citybrain.flow.platform.manager.common.client.HttpTerminateProcessInstanceDto;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.enums.CommentTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.ModelCustomConfigDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.monitor.ProcessInstanceActionVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowReModelCustomConfigRepository;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @author lilh
 * @date 2019-02-20 16:10
 */
@Service
public class TerminateProcessInstanceCommandHandler extends AbstractCommandHandler {

    @Override
    public String handleType() {
        return TERMINATE_PROCESS_INSTANCE;
    }

    @Autowired
    private FlowReModelCustomConfigRepository flowReModelCustomConfigRepository;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ProcessInstanceMonitorService processInstanceMonitorService;

    @Override
    public HttpCommandResultDto handle(String params) {
        HttpTerminateProcessInstanceDto terminateProcessInstanceDto = JSONObject.parseObject(params, HttpTerminateProcessInstanceDto.class);
        return handle(terminateProcessInstanceDto);
    }

    @Override
    public HttpCommandResultDto handle(HttpCommandDto commandDto) {
        HttpTerminateProcessInstanceDto terminateProcessInstanceDto = (HttpTerminateProcessInstanceDto) commandDto;

        CommonOperateLogHolder.getContent().setRequest(terminateProcessInstanceDto);
        ProcessInstance processInstance = resolveProcessInstance(terminateProcessInstanceDto.getProcessInstanceId());
        if (Objects.isNull(processInstance)) {
            logger.warn("流程实例不存在{}", terminateProcessInstanceDto.getProcessInstanceId());
            return resolveResult((String) null, ErrorCode.PROCESS_INSTANCE_NOT_EXIST.errMessage(), null);
        }

        String comment = terminateProcessInstanceDto.getComment();
        if (StringUtils.isBlank(comment)){
            boolean need = checkIsRequiredComment(terminateProcessInstanceDto.getWorkItemId());
            if (need){
                return resolveFailResult(terminateProcessInstanceDto.getProcessInstanceId(), ErrorCode.COMMENT_NOT_EXIST.errMessage());
            }
        }else{
            addComment(terminateProcessInstanceDto.getWorkItemId(),terminateProcessInstanceDto.getParticipantId(),processInstance.getProcessInstanceId(), CommentTypeEnum.LCZZ.getName(),comment);
        }


        ProcessInstanceActionVo processInstanceActionVo = new ProcessInstanceActionVo();
        Set<String> processInstanceIdSet = new HashSet<>();
        processInstanceIdSet.add(terminateProcessInstanceDto.getProcessInstanceId());
        processInstanceActionVo.setProcessInstanceIds(processInstanceIdSet);
        processInstanceActionVo.setAction(ProcessInstanceActionEnum.END.getCode());
        processInstanceActionVo.setUserCode(terminateProcessInstanceDto.getParticipantId());
        processInstanceActionVo.setUserName(terminateProcessInstanceDto.getParticipantName());
        boolean result = false;
        String errorMsg = null;
        try {
            result = processInstanceMonitorService.doActionWithoutUserCheck(processInstanceActionVo);
        }
        catch (Exception e) {
            logger.error("terminateProcessInstanceError:",e);
            errorMsg = e.getMessage();
        }
        if (result){
            return resolveResult(processInstance, null, TERMINATE_PROCESS_INSTANCE_SUCCESS);
        }
        if(null==errorMsg){
            errorMsg="terminateProcessInstanceError";
        }
        return resolveResult(errorMsg, null);
    }
}
